﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.WebAccess.WorkItemTracking.Controls;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using TimeSheetControl.ObjectModel;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.IO;
using System.Xml.Serialization; 

namespace TimeSheetControl.Web
{
    public class WorkItemTimeSheetControl : BaseWorkItemWebControl 
    {
        public WorkItemTimeSheetControl() 
            : base(HtmlTextWriterTag.Div) 
        { 

        }

        #region Web ControlS

        public Table DebugTable { get; set; }
        public Table EntryTable {get; set;}
        public Table DisplayTable {get; set;}

        public TextBox UserTextBox { get; set; }
        public TextBox  CommentsTextBox { get; set; }
        public TextBox EntryDateTextBox { get; set; }
        public TextBox HoursTextBox { get; set; }
        public Button AddButton { get; set; }
        public Repeater DataRepeater { get; set; }
        #endregion


        /// <summary> 
        /// The value in the work item 
        /// </summary> 
        public string FieldValue
        {
            get
            {
                // When it has a value, return that value 
                if (HasValidField && Field.Value != null)
                    return Field.Value.ToString();

                // Else return the empty string 
                return string.Empty;
            }
            set
            {
                // When the field is value and is editable 
                if (HasValidField && Field.FieldDefinition.IsEditable)
                    // And it is changed 
                    if ((Field.Value != null || value != null)
                        && (Field.Value == null || Field.Value.ToString() != value))
                    {
                        // Set the value in the work item 
                        base.OnBeforeUpdateDatasource(EventArgs.Empty);
                        Field.Value = value;
                        base.OnAfterUpdateDatasource(EventArgs.Empty);
                    }
            }
        }

        ///// <summary> 
        ///// The value of the textbox 
        ///// </summary> 
        //public string Value
        //{
        //    get
        //    {
        //        EnsureInnerControls();

        //        return TextBox.Text;
        //    }
        //    set
        //    {
        //        EnsureInnerControls();

        //        TextBox.Text = value;
        //    }
        //}

        /// <summary> 
        /// Build the control 
        /// </summary> 
        public override void InitializeControl()
        {
            base.InitializeControl();

            try
            {

                // Create the TextBox 
                EnsureInnerControls();

                // Save the value when it is changed 
                // TextBox.TextChanged += delegate { FlushToDatasource(); };

                LogMessage("After Ensure Initialize Controls ");
                this.InvalidateDatasource();
            }
            catch (Exception ex)
            {
                base.Controls.Clear();
                base.Controls.Add(new Label() { Text = ex.Message });
            }
        }

        private void LogMessage(string msg)
        {
            if (DebugTable != null){
                TableRow row = new TableRow();
                TableCell cell = new TableCell();
                cell.ColumnSpan = 4;
                cell.Controls.Add(new Label() { Text = msg });
                row.Cells.Add(cell);
                DebugTable.Rows.Add(row);
            }
        }
        /// <summary> 
        /// Add the textbox 
        /// </summary> 
        private void EnsureInnerControls()
        {
            
            if (EntryTable == null)
            {
                EntryTable = new Table() { Width=new Unit(100, UnitType.Percentage) };
                EntryTable.HorizontalAlign = HorizontalAlign.Left;


                TableHeaderRow EntryHeaderRow = new TableHeaderRow();

                TableHeaderCell EntryHeaderRow_UserCell = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left };
                EntryHeaderRow_UserCell.Controls.Add(new Label() { Text = "User" });
                EntryHeaderRow.Cells.Add(EntryHeaderRow_UserCell);

                TableHeaderCell EntryHeaderRow_DateCell = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left };
                EntryHeaderRow_DateCell.Controls.Add(new Label() { Text = "Date" });
                EntryHeaderRow.Cells.Add(EntryHeaderRow_DateCell);


                TableHeaderCell EntryHeaderRow_HoursCell = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left };
                EntryHeaderRow_HoursCell.Controls.Add(new Label() { Text = "Hours" });
                EntryHeaderRow.Cells.Add(EntryHeaderRow_HoursCell);

                TableHeaderCell EntryHeaderRow_CommentsCell = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left };
                EntryHeaderRow_CommentsCell.Controls.Add(new Label() { Text = "Comments" });
                EntryHeaderRow.Cells.Add(EntryHeaderRow_CommentsCell);

                TableHeaderCell EntryHeaderRow_AddButtonCell = new TableHeaderCell();
                EntryHeaderRow.Cells.Add(EntryHeaderRow_AddButtonCell);

                TableRow EntryRow = new TableRow();


                TableCell EntryRow_UserCell = new TableCell();
                UserTextBox  = new TextBox();
                UserTextBox.Text  = System.Web.HttpContext.Current.User.Identity.Name;
                UserTextBox.Enabled = false;
                EntryRow_UserCell.Controls.Add(UserTextBox);
                EntryRow.Cells.Add(EntryRow_UserCell);

                TableCell EntryRow_DateCell = new TableCell();
                EntryDateTextBox = new TextBox();
                EntryDateTextBox.Text = DateTime.Now.ToShortDateString();
                EntryRow_DateCell.Controls.Add(EntryDateTextBox);
                EntryRow.Cells.Add(EntryRow_DateCell);

                TableCell EntryRow_HoursCell = new TableCell();
                HoursTextBox = new TextBox();
                EntryRow_HoursCell.Controls.Add(HoursTextBox);
                EntryRow.Cells.Add(EntryRow_HoursCell);

                TableCell EntryRow_CommentsCell = new TableCell();
                CommentsTextBox = new TextBox();
                EntryRow_CommentsCell.Controls.Add(CommentsTextBox);
                EntryRow.Cells.Add(EntryRow_CommentsCell);

                TableCell EntryRow_AddButtonCell = new TableCell();
                AddButton = new Button() { Text = "Add", Width = new Unit(100, UnitType.Pixel) };
                AddButton.Click += new EventHandler(AddButton_Click);
                EntryRow_AddButtonCell.Controls.Add(AddButton);
                EntryRow.Cells.Add(EntryRow_AddButtonCell);

                EntryTable.Rows.Add(EntryHeaderRow);
                EntryTable.Rows.Add(EntryRow);
            }   

            if (DisplayTable == null)
            {
                DisplayTable = new Table() { Width=new Unit(100, UnitType.Percentage), Height=new Unit(100, UnitType.Percentage) };
                
            }

            if (DebugTable == null)
            {
                DebugTable = new Table() { Width = new Unit(100, UnitType.Percentage), Height = new Unit(100, UnitType.Percentage) };
            }
            base.Controls.Clear();

            base.Controls.Add(EntryTable);

            //TableRow dataRow = new TableRow();
            //TableCell dataCell = new TableCell();
            //dataCell.ColumnSpan = 4;
            //dataCell.Controls.Add(DisplayTable);
            //dataRow.Cells.Add(dataCell);
            //EntryTable.Rows.Add(dataRow);

            //TableRow debugRow = new TableRow();
            //TableCell debugCell = new TableCell();
            //debugCell.ColumnSpan = 4;
            //debugCell.Controls.Add(DebugTable);
            //debugRow.Cells.Add(debugCell);
          //  EntryTable.Rows.Add(debugRow);

            LogMessage("End of Ensure Inner Controls");

        }

        

        /// <summary> 
        /// THe underlying data is changed. Change the contents of the TextBox accordingly 
        /// </summary> 



        private WorkItem CurrentWorkItem
        {
            get
            {
                return base.WorkItemDatasource as WorkItem;
            }
        }

        private TimeSheet TimeSheet { get; set; }

        public override void InvalidateDatasource()
        {
            LogMessage( "InvalidateDataSource" );
            base.InvalidateDatasource();

            // Validate that the WorkItemFieldName property has been set
            if (string.IsNullOrEmpty(WorkItemFieldName))
            {
                throw new ArgumentNullException("The fieldname property for the WorkItemTimeSheetControl is not set");
            }

            // Reset the form to default values
            TimeSheet = null;
            EntryDateTextBox.Text = DateTime.Today.ToShortDateString();
            HoursTextBox.Text = "1";
            CommentsTextBox.Text = string.Empty;
            for (int i = (EntryTable.Rows.Count - 1); i >= 0;  i-- )
            {
                if (i >= 2)
                {
                    EntryTable.Rows.RemoveAt(i);
                }
            }


            LogMessage("InvalidateDataSource 1");


            // CurrentWorkItem can be null when unloading a work item form
            if (CurrentWorkItem == null)
            {
                LogMessage("CurrentWorkItem is currently null.  ");
                return;
            }


            LogMessage("InvalidateDataSource 2");

            TimeSheet = GetCurrentTimesheet();
            //////DisplayTable.Rows.Clear();

            //////TableHeaderRow headerRow = new TableHeaderRow();
            //////TableHeaderCell userHeader = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left } ;
            //////userHeader.Controls.Add(new Label() { Text = "User" });

            //////TableHeaderCell dateHeader = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left };
            //////dateHeader.Controls.Add(new Label() { Text = "Date" });

            //////TableHeaderCell hoursHeader = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left };
            //////hoursHeader.Controls.Add(new Label() { Text = "Hours" });

            //////TableHeaderCell commentsHeader = new TableHeaderCell() { HorizontalAlign = HorizontalAlign.Left };
            //////commentsHeader.Controls.Add(new Label() { Text = "Comments" });

            //////TableHeaderCell deleteHeader = new TableHeaderCell();

            //////headerRow.Cells.Add(userHeader);
            //////headerRow.Cells.Add(dateHeader);
            //////headerRow.Cells.Add(hoursHeader);
            //////headerRow.Cells.Add(commentsHeader);
            //////headerRow.Cells.Add(deleteHeader);
            //////DisplayTable.Rows.Add(headerRow);
            
            // TODO: Add header row

            LogMessage("InvalidateDataSource 3 (Count: " + TimeSheet.Count + ")");
            foreach (TimeSheetEntry entry in TimeSheet)
            {
                TableRow row = new TableRow();
                TableCell user = new TableCell();
                user.Controls.Add(new Label() { Text = entry.CreatedBy });
                
                TableCell date = new TableCell();
                date.Controls.Add(new Label() { Text = entry.CreatedDate.ToShortDateString() });

                TableCell hours = new TableCell();
                hours.Controls.Add(new Label() { Text = string.Format("{0:f2}", entry.Hours) });

                TableCell comments = new TableCell();
                comments.Controls.Add(new Label() { Text = entry.Comments });

                TableCell delete = new TableCell();
                Button deleteLink = new Button() { Text = "Delete" };
                deleteLink.CommandArgument = TimeSheet.IndexOf(entry).ToString();
                deleteLink.Click +=new EventHandler(deleteLink_Click);
                //delete.Controls.Add(deleteLink);

                row.Cells.Add(user);
                row.Cells.Add(date);
                row.Cells.Add(hours);
                row.Cells.Add(comments);
                row.Cells.Add(delete);
                
                EntryTable.Rows.Add(row);
            }
            
            ResetStyles();
        }

        private TimeSheet GetCurrentTimesheet()
        {
            TimeSheet timeSheet = null;
            // Load the timesheet data from the work item if it is available.
            if (CurrentWorkItem.Fields[WorkItemFieldName].Value == null
                || string.IsNullOrEmpty(CurrentWorkItem.Fields[WorkItemFieldName].Value.ToString()))
            {
                timeSheet = new TimeSheet();
            }
            else
            {
                timeSheet = TimeSheet.Deserialize(CurrentWorkItem.Fields[WorkItemFieldName].Value.ToString());
            }
            return timeSheet;
        }

        /// <summary> 
        /// Ensure that the control is correctly shows (width + enabled) 
        /// </summary> 
        private void ResetStyles()
        {
            LogMessage("Reset Styles");
            Width = Unit.Percentage(100);
            Enabled = !ControlReadOnly && !EditorReadOnly;
        }

        void  deleteLink_Click(object sender, EventArgs e)
        {
            LogMessage("Delete Clicked");
            return;

            ////decimal completedWork = GetCompletedWork();
            ////decimal remainingWork = GetRemainingWork();

            ////Button btn = sender as Button;

            //////TimeSheet timeSheet = GetCurrentTimesheet();
            ////TimeSheetEntry tse = TimeSheet[int.Parse(btn.CommandArgument)];
            ////TimeSheet.Remove(tse);

            ////remainingWork += (tse.Minutes / 60);
            ////completedWork -= (tse.Minutes / 60);

            ////if (completedWork < 0)
            ////    completedWork = 0;

            ////CurrentWorkItem.Fields[WorkItemFieldName].Value = TimeSheet.Serialize(TimeSheet);

            ////SetCompletedWork(completedWork);
            ////SetRemainingWork(remainingWork);

            //////FlushToDatasource();

            ////LogMessage("Delete Clicked 2");
            //////InvalidateDatasource();
        }

        void AddButton_Click(object sender, EventArgs e)
        {
            LogMessage("Add Clicked");
            
            TimeSheetEntry tse = new TimeSheetEntry();
            tse.CreatedBy = UserTextBox.Text;
            tse.CreatedDate = DateTime.Now;
            tse.Minutes = decimal.Parse(HoursTextBox.Text) * 60;
            tse.TimeSheetDate = DateTime.Parse(EntryDateTextBox.Text);
            tse.Comments = CommentsTextBox.Text;
            TimeSheet.Add(tse);
            CurrentWorkItem.Fields[WorkItemFieldName].Value = TimeSheet.Serialize(TimeSheet);

            decimal completedWork = GetCompletedWork();

            completedWork = completedWork + (tse.Minutes / 60);
            SetCompletedWork(completedWork);


            // Reduce the 'Remaining Work'

            decimal remainingWork = GetRemainingWork();

            remainingWork = remainingWork - (tse.Minutes / 60);

            if (remainingWork < 0)
                remainingWork = 0;

            SetRemainingWork(remainingWork);

            FlushToDatasource();

            CurrentWorkItem.Save();
        }


        private void SetRemainingWork(decimal remainingWork)
        {
            CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value = remainingWork;
        }

        private void SetCompletedWork(decimal completedWork)
        {
            CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value = completedWork;
        }

        private decimal GetCompletedWork()
        {
            decimal completedWork = 0;
            // Add to the 'Completed Work' 
            if (CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"] != null
                && CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value != null
                && !string.IsNullOrEmpty(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value.ToString()))
            {

                decimal.TryParse(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value.ToString(), out completedWork);
            }
            return completedWork;
        }

        private decimal GetRemainingWork()
        {
            decimal remainingWork = 0;
            // Add to the 'Completed Work' 
            if (CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"] != null
                && CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value != null
                && !string.IsNullOrEmpty(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value.ToString()))
            {

                decimal.TryParse(CurrentWorkItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value.ToString(), out remainingWork);
            }
            return remainingWork;
        }

    }
}
